package com.wits.platform.web.controller;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.ExpiredCredentialsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.PasswordService;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springside.modules.web.Servlets;

import com.wits.platform.common.constants.ViewType;
import com.wits.platform.common.constants.WebConstants;
import com.wits.platform.common.utils.DateUtil;
import com.wits.platform.common.utils.ExportExcelUtil;
import com.wits.platform.common.utils.PageUtil;
import com.wits.platform.common.utils.StringUtil;
import com.wits.platform.entity.User;
import com.wits.platform.service.UserService;
import com.wits.platform.service.account.LoginCommand;
import com.wits.platform.service.account.ShiroUser;
import com.wits.platform.web.mvc.AjaxResult;
import com.wits.platform.web.mvc.PageParam;
import com.wits.qso.service.StudentService;
import com.wits.qso.service.TeacherService;


@Controller
@RequestMapping("/user")
public class UserController extends BaseController{


	@Autowired
	private UserService userService;
	
	@Autowired
	private TeacherService teacherService;
	@Autowired
	private StudentService studentService;

	@Autowired
	private PasswordService passwordService;

	@RequestMapping(value = "/toRadioUser")
	public String toRadioUser(){
		return "platform/user/radioUser";
	}


	@RequestMapping(value = "/toList")
	public String toList(){
		return "platform/user/list";
	}

	@RequestMapping(value = "/list")
	@ResponseBody
	public String list(Model model,@ModelAttribute("page") PageParam page,HttpServletRequest req) {
		Map<String, Object> searchParams = Servlets.getParametersStartingWith(req, "search_");
		Page<User> listPage = userService.findPage(searchParams,page);
		model.addAttribute("searchParams", Servlets.encodeParameterStringWithPrefix(searchParams, "search_"));
		return PageUtil.toAjaxPageResult(listPage.getTotalElements(),listPage.getContent());
	}

	@RequestMapping(value = "/view/{viewType}")
	public String toView(Model model,@PathVariable String viewType,@RequestParam String userId){
		if(ViewType.Add.getView().equals(viewType)){
			model.addAttribute(WebConstants.COMMAND,new User());
		}else{
			model.addAttribute(WebConstants.COMMAND,  userService.getOne(userId));
		}
		model.addAttribute("viewType",viewType);
		return "platform/user/form";
	}

	@RequestMapping(value = "/save", method = {RequestMethod.POST})
	@ResponseBody
	public Object save(Model model,@ModelAttribute("command") @Valid User command,@RequestParam String viewType,BindingResult result,HttpServletRequest req) {
		if(result.hasErrors()) {
			model.addAttribute(WebConstants.COMMAND, command);
			return toView(model,viewType,command.getUserId());
		}
		String encrypted = passwordService.encryptPassword(command.getUserPassword());  
		command.setUserPassword(encrypted);
		if(ViewType.Add.getView().equals(viewType)){
			command.setUserCre(getCurrentUserId());
			command.setDateCre(new Date());
			userService.saveCascade(command);
		}else{
			command.setUserUpd(getCurrentUserId());
			command.setDateUpd(new Date());
			userService.updateCascade(command);
		}
		return ajaxDoneSuccess(this.getText("save.success"));
	}
	
	@RequestMapping(value = "/isExitUser", method = RequestMethod.POST)
	@ResponseBody
	public Object isExitUser(@ModelAttribute LoginCommand loginCommand, HttpServletRequest req) {
		AjaxResult result=null;
		loginCommand.setUserId(getCurrentUserId());
		result=doLogin(loginCommand,req);
		return result;
	}

	@RequestMapping(value = "/update")
	@ResponseBody 
	public Object update( HttpServletRequest request,@RequestParam String userType,@RequestParam String firstPwd,@RequestParam String newPwd) {
		
		User user;
		if(userType=="stu")
			user=studentService.getUser(getCurrentUserId());
		else
			user=teacherService.getUser(getCurrentUserId());
		user.setUserUpd(getCurrentUserId());
		user.setUserPassword(passwordService.encryptPassword(newPwd));
		user.setDateUpd(new Date());
		userService.update(user);
		return ajaxDoneSuccess(this.getText("update.success"));
	}
	
	protected AjaxResult doLogin(LoginCommand command, HttpServletRequest request){
    	AjaxResult result=null;
		UsernamePasswordToken token = new UsernamePasswordToken(command.getUserId(),command.getPassword());
		try {
			this.setLocale(command.getLocale());
			Subject subject=SecurityUtils.getSubject();
			subject.login(token);
			ShiroUser shiroUser=(ShiroUser)subject.getPrincipals().getPrimaryPrincipal();
			userService.updateLoginStatus(shiroUser.getId(),StringUtil.getIpAddr(request));
			result=ajaxDoneSuccess(shiroUser);
		} catch(Exception e){
			e.printStackTrace();
			result=ajaxDoneError(this.getText("errors.user.password"));
		}
		return result;
	}

	@RequestMapping(value = "/changeEnable")
	@ResponseBody
	public Object changeEnable(@RequestParam(value="id") String id,@RequestParam(value="isEnable") String isEnable){
		try {
			userService.updateEnable(id,isEnable);
			return ajaxDoneSuccess(this.getText("update.success"));
		} catch (Exception e) {
			return ajaxDoneError(this.getText("update.failed"),e);
		}

	}

	@RequestMapping(value = "/delete")
	@ResponseBody
	public Object delete(String ids) {
		try {
			ids=StringUtil.decorator("'",StringUtils.split(ids, ","));
			userService.deleteInBatch(ids);
			return ajaxDoneSuccess(this.getText("delete.success"));
		} catch (Exception e) {
			return ajaxDoneError(this.getText("delete.failed"),e);
		}
	}

	@RequestMapping(value = "/checkUserId")
	@ResponseBody
	public boolean checkUserId(@RequestParam("oldUserId") String oldUserId,
			@RequestParam("userId") String userId) {
		if (userId.equals(oldUserId)) {
			return true;
		} 
		User user=userService.getOne(userId);
		return user==null;
	}


	@RequestMapping(value = "/exportExcel")
	public void exportExcel(Model model,@ModelAttribute("page") PageParam page,HttpServletRequest req,HttpServletResponse res){
		Map<String, Object> searchParams = Servlets.getParametersStartingWith(req, "search_");
		Page<User> listPage = userService.findPage(searchParams,page);
		ExportExcelUtil<User> ex = new ExportExcelUtil<User>();

		String[] headers = {"账号", "角色", "状态", "账号有效期","上一次登陆时间","上一次登陆ip","创建日期 "};
		String[] fieldNames={"account","roles","status","availablePeriod","lastLoginTime","lastLoginIp","addTime"};
		res.setHeader("Connection", "close");
		res.setHeader("content-type", "application/octet-stream");
		res.setHeader("content-Disposition", "attachment;filename="+ DateUtil.currentTime()+ ".xls");
		OutputStream out=null;
		try {
			out = res.getOutputStream();
			ex.exportExcel(headers,fieldNames,listPage.getContent(), out);
		} catch (IOException e) {
		}finally{
			if(out!=null){
				try {
					out.flush();
					out.close();
				} catch (IOException e) {
				}
			}
		}

	}

}
